import { Box, TextField, InputAdornment, IconButton, Button, TableContainer, Table, TableHead, TableRow, Checkbox, TableBody, TableFooter, Switch, FormControlLabel, InputBase } from '@mui/material';
import React, { JSX } from 'react';
import { useAppSelector, useAppDispatch } from '../../actions/hook';
import { NulHeaderTableCell, NulTableCell } from '../../components/NulHeaderTable';
import { removeElementFromArray } from '../../util/Arrays';
import ClearIcon from '@mui/icons-material/Clear';
import { ReactComponent as SearchIcon } from '../../assets/search.svg';
import { ReactComponent as CreateIcon } from '../../assets/create.svg';
import DeleteIcon from '@mui/icons-material/Delete';
import { InvoiceEntry, IssueInvoiceRequestEntry, deleteIssueInvoice, issueInvoice, modifyIssueInvoiceQuantity, selectIssueInvoiceGrossProfit, selectIssueInvoiceTotalAmount, switchPriceType } from '../../actions/IssueInvoice';
import { selectInvoiceEntries } from '../../actions/InvoiceOperations';
import AutorenewIcon from '@mui/icons-material/Autorenew';
import SwitchInventoryDialog from '../InventoryDialog/SwitchInventoryDialog';
import { fetchAllWarehouse, selectWarehouseEntries, selectWarehouseFetched } from '../../actions/WarehouseManagement';
import CreateInvoiceEntryDialog from '../IssueInvoiceDialog/CreateInvoiceEntryDialog';
import CheckIcon from '@mui/icons-material/Check';
import { fetchAllInventoryEntries, fetchAvailableWarehouses, selectInventoryAvailableWarehouses, selectInventoryAvailableWarehousesFetched, selectInventoryEntries, selectInventoryWarehouseId, switchWarehouse } from '../../actions/InventoryManagement';
import { AlertBox } from '../../components/AlertBox';

interface InvoiceOperationsPageProps {
  id: string;
}

function InvoiceOperationsPage(props: InvoiceOperationsPageProps): JSX.Element {

  const [filterValue, setFilterValue] = React.useState<string>('');
  const [openIssueInvoiceDialog, setOpenIssueInvoiceDialog] = React.useState<boolean>(false);
  const [openSwitchDialog, setOpenSwitchDialog] = React.useState<boolean>(false);
  const [openInvalidQuantityAlert, setOpenInvalidQuantityAlert] = React.useState<boolean>(false);

  const [filteredInvoiceEntries, setFilteredInvoiceEntries] = React.useState<InvoiceEntry[]>([]);
  const [checkedIdList, setCheckedIdList] = React.useState<number[]>([]);

  const [typeSwitchChecked, setTypeSwitchChecked] = React.useState<boolean>(true);

  const invoiceEntries = useAppSelector(selectInvoiceEntries);
  const warehouseEntries = useAppSelector(selectWarehouseEntries);
  const warehouseEntriesFetched = useAppSelector(selectWarehouseFetched);
  const inventoryEntries = useAppSelector(selectInventoryEntries);
  const inventoryWarehouseId = useAppSelector(selectInventoryWarehouseId);
  const inventoryAvailableFetched = useAppSelector(selectInventoryAvailableWarehousesFetched);
  const inventoryAvailableWarehouses = useAppSelector(selectInventoryAvailableWarehouses);
  const invoiceGrossProfit = useAppSelector(selectIssueInvoiceGrossProfit);
  const invoiceTotalAmount = useAppSelector(selectIssueInvoiceTotalAmount);


  const dispatch = useAppDispatch();

  const handleDelete = (row: InvoiceEntry) => {
    dispatch(deleteIssueInvoice(row.id));
  };

  const handleBatchDelete = () => {
    for (let i = 0; i < checkedIdList.length; ++i) {
      dispatch(deleteIssueInvoice(checkedIdList[i]));
    }
  };

  const handleSubmit = () => {
    const request: IssueInvoiceRequestEntry[] = [];
    for (let i = 0; i < invoiceEntries.length; ++i) {
      const quantityNumber: number = parseInt(invoiceEntries[i].quantity);
      if (isNaN(quantityNumber) || quantityNumber <= 0) {
        setOpenInvalidQuantityAlert(true);
        return;
      }
      request.push({ id: invoiceEntries[i].id, quantity: quantityNumber });
    }
    dispatch(issueInvoice({
      entries: request, type: typeSwitchChecked ? 'retail' : 'wholesale', warehouseId: inventoryWarehouseId
    }));
  };

  React.useEffect(() => {
    dispatch(switchPriceType(typeSwitchChecked));
  }, [typeSwitchChecked, dispatch]);

  React.useEffect(() => {
    if (!warehouseEntriesFetched) {
      dispatch(fetchAllWarehouse());
    }
    if (!inventoryAvailableFetched) {
      dispatch(fetchAvailableWarehouses());
    }
  });

  React.useEffect(() => {
    if (inventoryAvailableFetched && inventoryAvailableWarehouses.length > 0) {
      dispatch(fetchAllInventoryEntries({ warehouseId: inventoryWarehouseId }));
    }
  }, [inventoryAvailableFetched, inventoryAvailableWarehouses, inventoryWarehouseId, dispatch]);

  React.useEffect(() => {
    if (invoiceEntries !== undefined) {
      setFilteredInvoiceEntries(invoiceEntries.filter(val => val.name.indexOf(filterValue) !== -1));
      setCheckedIdList([]);
    }
  }, [invoiceEntries, filterValue]);

  const headerChecked: boolean = checkedIdList.length !== 0 && checkedIdList.length === filteredInvoiceEntries.length;
  const headerIndeterminate: boolean = checkedIdList.length !== 0 && checkedIdList.length < filteredInvoiceEntries.length;

  return (
    <>
      <Box sx={{ padding: '30px 30px 30px 30px', flex: 'none', flexGrow: 1 }}>
        <Box sx={{
          fontFamily: 'Open Sans',
          fontStyle: 'normal',
          fontWeight: 600,
          fontSize: '22px',
          lineHeight: '125%',
          display: 'flex',
          flexDirection: 'row'
        }}>
          <Box>
            Issue Invoice
          </Box>
          <Button
            startIcon={<AutorenewIcon />} sx={{ marginLeft: '10px', textTransform: 'none' }}
            onClick={() => { setOpenSwitchDialog(true); }}
          >
            Switch
          </Button>
        </Box>
        <Box sx={{
          marginTop: '20px', width: '100%', height: '40px', display: 'flex',
          flexDirection: 'row', justifyContent: 'space-between'
        }}>
          <Box sx={{ width: '456px' }}>
            <TextField
              size='small'
              fullWidth={true}
              InputProps={{
                startAdornment: (
                  <InputAdornment position='start' sx={{}}>
                    <SearchIcon />
                  </InputAdornment>
                ),
                endAdornment: (
                  <IconButton edge="end" onClick={() => { setFilterValue(''); }}>
                    <ClearIcon fontSize='small' />
                  </IconButton>
                )
              }}
              placeholder='Search supplier'
              value={filterValue}
              onChange={(action) => { setFilterValue(action.target.value); }}
              sx={{
                paddingLeft: '0px'
              }}
            />
          </Box>
          <Box sx={{
            flex: 'none',
            order: 1,
            flexGrow: 0
          }}>
            <Button
              variant='contained'
              disableElevation
              startIcon={<DeleteIcon />}
              onClick={handleBatchDelete}
              sx={{
                height: '40px',
                textTransform: 'none',
                marginRight: '10px'
              }}
              color='error'
            >
              Delete
            </Button>
            <Button
              variant="contained"
              disableElevation
              startIcon={<CreateIcon />}
              onClick={() => {
                setOpenIssueInvoiceDialog(true);
              }}
              sx={{
                height: '40px',
                textTransform: 'none',
                marginRight: '10px'
              }}
            >
              Create
            </Button>
            <Button
              variant="contained"
              disableElevation
              startIcon={<CheckIcon />}
              onClick={handleSubmit}
              sx={{
                height: '40px',
                textTransform: 'none'
              }}
            >
              Submit
            </Button>
          </Box>
        </Box>
        <Box sx={{
          marginTop: '20px',
          width: '100%'
        }}>
          <TableContainer
            sx={{
              width: '100%'
            }}
          >
            <Table
              stickyHeader
              sx={{
                border: '1px solid #DFE4E8',
                borderRadius: '8px',
                fontFamily: 'Open Sans',
                fontStyle: 'normal',
              }}
            >
              <TableHead sx={{ border: '8px 8px 0px 0px' }}>
                <TableRow sx={{
                  height: '42px',
                  padding: 0,
                  width: '100%',
                  display: 'flex',
                  alignItems: 'center',
                }}>
                  <Box sx={{ height: '100%' }}>
                    <NulHeaderTableCell
                      sx={{
                        width: '62px',
                        borderTopLeftRadius: '8px',
                        justifyContent: 'center',
                        flexGrow: 0
                      }}
                    >
                      <Checkbox
                        sx={{
                          width: '42px',
                          display: 'flex',
                          justifyContent: 'center',
                        }}
                        onClick={() => {
                          if (headerChecked) {
                            setCheckedIdList([]);
                          }
                          else {
                            setCheckedIdList(filteredInvoiceEntries.map(entry => entry.id));
                          }
                        }}
                        checked={headerChecked}
                        indeterminate={headerIndeterminate}
                      />
                    </NulHeaderTableCell>
                  </Box>
                  <Box sx={{ display: 'flex', flexDirection: 'row', flexGrow: 1, position: 'relative', height: '100%' }}>
                    <NulHeaderTableCell sx={{ width: '5%' }}>
                      ID
                    </NulHeaderTableCell>
                    <NulHeaderTableCell sx={{ width: '25%' }}>
                      Name
                    </NulHeaderTableCell>
                    <NulHeaderTableCell sx={{ width: '15%' }}>
                      Quantity
                    </NulHeaderTableCell>
                    <NulHeaderTableCell sx={{ width: '20%' }}>
                      {typeSwitchChecked ? 'Retail Price' : 'Wholesale Price'}
                    </NulHeaderTableCell>
                    <NulHeaderTableCell sx={{ width: '20%' }}>
                      Cost Price
                    </NulHeaderTableCell>
                    <NulHeaderTableCell sx={{ width: '25%', borderTopRightRadius: '8px', }}>
                      Operations
                    </NulHeaderTableCell>
                  </Box>
                </TableRow>
              </TableHead>
              <TableBody
                sx={{
                  minHeight: '390px', maxHeight: '390px', display: 'block', overflowY: 'auto'
                }}
              >
                {filteredInvoiceEntries.map(row => {
                  const checkedIndex: number = checkedIdList.indexOf(row.id);
                  return (
                    <TableRow
                      key={row.id}
                      sx={{
                        width: '100%',
                        display: 'flex',
                        alignItems: 'center',
                        height: '42px'
                      }}
                    >
                      <Box sx={{ height: '100%' }}>
                        <NulTableCell sx={{ width: '62px', justifyContent: 'center', flexGrow: 0 }}>
                          <Checkbox
                            sx={{
                              width: '42px',
                              display: 'flex',
                              justifyContent: 'center',
                            }}
                            checked={checkedIndex !== -1}
                            onChange={(event, checked) => {
                              if (checked) {
                                if (checkedIndex === -1) {
                                  setCheckedIdList([...checkedIdList, row.id]);
                                }
                              }
                              else {
                                if (checkedIndex !== -1) {
                                  setCheckedIdList(removeElementFromArray(checkedIdList, checkedIndex));
                                }
                              }
                            }}
                          />
                        </NulTableCell>
                      </Box>
                      <Box sx={{ display: 'flex', flexDirection: 'row', flexGrow: 1, position: 'relative', height: '100%' }}>
                        <NulTableCell sx={{ width: '5%' }}>
                          {row.id}
                        </NulTableCell>
                        <NulTableCell sx={{ width: '25%' }}>
                          {row.name}
                        </NulTableCell>
                        <NulTableCell sx={{ width: '15%' }}>
                          <InputBase placeholder='Quantity' size='small' fullWidth={true}
                            value={row.quantity}
                            onChange={(action) => {
                              const value: string = action.target.value;
                              dispatch(modifyIssueInvoiceQuantity({ id: row.id, quantity: value }));
                            }}
                            sx={{
                              '& .MuiInputBase-input': {
                                'padding': 0
                              }
                            }}
                            inputProps={{
                              inputRoot: {
                                border: 'none',
                                boxShadow: 'none'
                              }
                            }} />
                        </NulTableCell>
                        <NulTableCell sx={{ width: '20%' }}>
                          {typeSwitchChecked ? row.retailPrice : row.wholesalePrice}
                        </NulTableCell>
                        <NulTableCell sx={{ width: '20%' }}>
                          {row.costPrice}
                        </NulTableCell>
                        <NulTableCell sx={{ width: '25%', display: 'flex' }}>
                          <IconButton aria-label='delete' onClick={() => { handleDelete(row); }}>
                            <DeleteIcon />
                          </IconButton>
                        </NulTableCell>
                      </Box>
                    </TableRow>
                  );
                })}
              </TableBody>
              <TableFooter
                sx={{
                  minHeight: '34px',
                  maxHeight: '44px',
                  display: 'flex',
                  backgroundColor: '#F1F3F5',
                  borderRadius: '0px 0px 8px 8px',
                  padding: '2px 16px 2px 16px',
                  flexDirection: 'row',
                  justifyContent: 'space-between',
                }}
              >
                <Box>
                  <FormControlLabel
                    control={
                      <Switch checked={typeSwitchChecked} onChange={(event) => { setTypeSwitchChecked(event.target.checked); }} />
                    }
                    label={typeSwitchChecked ? 'Retail' : 'Wholesale'}
                    sx={{
                      fontFamily: 'Open Sans'
                    }}
                  />
                </Box>
                <Box sx={{ fontFamily: 'Open Sans', paddingTop: '10px', paddingBottom: '10px' }}>
                  Total: {invoiceTotalAmount} Profit: {invoiceGrossProfit}
                </Box>
              </TableFooter>
            </Table>
          </TableContainer>
        </Box>
      </Box>
      <SwitchInventoryDialog
        open={openSwitchDialog}
        onClose={() => { setOpenSwitchDialog(false); }}
        onResult={(id: number) => { dispatch(switchWarehouse(id)); }}
        warehouseEntries={warehouseEntries}
      />
      <CreateInvoiceEntryDialog
        open={openIssueInvoiceDialog}
        onClose={() => { setOpenIssueInvoiceDialog(false); }}
        inventoryEntries={inventoryEntries}
        warehouseId={inventoryWarehouseId}
      />
      <AlertBox
        open={openInvalidQuantityAlert}
        onClose={() => { setOpenInvalidQuantityAlert(false); }}
        title='Error'
        message='Invalid quantity in issue invoice.'
        autoHideDuration={4000}
      />
    </>
  );
}

export default InvoiceOperationsPage;